#!/bin/sh

LABEL=b2d-data
MAGIC="boot2docker, please format-me"
UNPARTITIONED_HD="/dev/$(lsblk | grep disk | grep ".*da" | cut -f1 -d' ')"

# Function to mount partitions
mount_partitions() {
    PARTNAME=`echo "$BOOT2DOCKER_DATA" | sed 's/.*\///'`
    echo "mount p:$PARTNAME ..."
    mkdir -p /mnt/$PARTNAME
    if ! mount $BOOT2DOCKER_DATA /mnt/$PARTNAME 2>/dev/null; then
        # for some reason, mount doesn't like to modprobe btrfs
        BOOT2DOCKER_FSTYPE=`blkid -o export $BOOT2DOCKER_DATA | grep TYPE= | cut -d= -f2`
        modprobe $BOOT2DOCKER_FSTYPE || true
        umount -f /mnt/$PARTNAME || true
        mount $BOOT2DOCKER_DATA /mnt/$PARTNAME
    fi

    # Activate swap partition
    echo "activate swap ..."
    swapon "${UNPARTITIONED_HD}2"

    # Just in case, the links will fail if not
    umount -f /var/lib/docker || true
    rm -rf /var/lib/docker /var/lib/boot2docker /var/lib/minishift /opt

    # Detected a disk with a normal linux install (/var/lib/docker + more))
    if [ ! -d "/var/lib" ]; then
        mkdir -p /var/lib
    fi

    if [ -d "/etc/pki/consumer" ]; then
        rm -fr /etc/pki/consumer /etc/pki/entitlement /etc/pki/product
        mkdir -p /mnt/$PARTNAME/etc/pki/{consumer,entitlement,product}
        ln -s /mnt/$PARTNAME/etc/pki/consumer /etc/pki/consumer
        ln -s /mnt/$PARTNAME/etc/pki/entitlement /etc/pki/entitlement
        ln -s /mnt/$PARTNAME/etc/pki/product /etc/pki/product
    fi

    mkdir -p /mnt/$PARTNAME/var/lib/docker
    mkdir -p /var/lib/docker
    mount --bind /mnt/$PARTNAME/var/lib/docker /var/lib/docker
    restorecon -R /var/lib/docker

    mkdir -p /mnt/$PARTNAME/var/lib/boot2docker
    mkdir -p /var/lib/boot2docker
    mount --bind /mnt/$PARTNAME/var/lib/boot2docker /var/lib/boot2docker

    mkdir -p /mnt/$PARTNAME/var/lib/boot2docker/etc/docker
    cp -r /etc/docker/* /mnt/$PARTNAME/var/lib/boot2docker/etc/docker
    rm -rf /etc/docker
    mkdir -p /etc/docker
    mount --bind /mnt/$PARTNAME/var/lib/boot2docker/etc/docker /etc/docker

    mkdir -p /mnt/$PARTNAME/var/lib/minishift
    mkdir -p /var/lib/minishift
    mount --bind /mnt/$PARTNAME/var/lib/minishift /var/lib/minishift

    mkdir -p /mnt/$PARTNAME/var/lib/origin
    mkdir -p /var/lib/origin
    mount --bind /mnt/$PARTNAME/var/lib/origin /var/lib/origin

    mkdir -p /mnt/$PARTNAME/opt
    ln -s /mnt/$PARTNAME/opt /opt

    # Move userdata to persistent storage
    if [ -e "/userdata.tar" ]; then
        mv /userdata.tar /var/lib/boot2docker/
    fi

    ls -l /mnt/$PARTNAME
}

# Function to partion and format the data disk
prepare_partions() {
    # Create the partition, format it and then mount it
    echo "NEW boot2docker managed disk image ($UNPARTITIONED_HD): formatting it for use"

    # Add a swap partition (so Docker doesn't complain about it missing)
    (echo n; echo p; echo 2; echo ; echo +1000M ; echo w) | fdisk $UNPARTITIONED_HD
    # Let kernel re-read partition table
    partprobe

    (echo t; echo 82; echo w) | fdisk $UNPARTITIONED_HD
    # Let kernel re-read partition table
    partprobe
    # wait for the partition to actually exist, timeout after about 5 seconds
    local timer=0
    while [ "$timer" -lt 10 -a ! -b "${UNPARTITIONED_HD}2" ]; do
        timer=$((timer + 1))
        sleep 0.5
    done

    # Prepare the swap partition
    mkswap "${UNPARTITIONED_HD}2"

    # Add the data partition
    (echo n; echo p; echo 1; echo ; echo ; echo w) | fdisk $UNPARTITIONED_HD
    # Let kernel re-read partition table
    partprobe
    # wait for the partition to actually exist, timeout after about 5 seconds
    timer=0
    while [ "$timer" -lt 10 -a ! -b "${UNPARTITIONED_HD}1" ]; do
        timer=$((timer + 1))
        sleep 0.5
    done

    BOOT2DOCKER_DATA=`echo "${UNPARTITIONED_HD}1"`
    mkfs.xfs -n ftype=1 -i size=2048 -L $LABEL $BOOT2DOCKER_DATA
}

# Function to extract userdata.tar containing the ssh keys into the home directory /home/docker
handle_user_data() {
    # Extract the userdata into docker user home directory
    if [ -e "/var/lib/boot2docker/userdata.tar" ]; then
        tar xf /var/lib/boot2docker/userdata.tar -C /home/docker/ > /var/log/userdata.log 2>&1
        rm -f '/home/docker/boot2docker, please format-me'
        chown -R docker:docker /home/docker/.ssh
    else
        echo "Unable to find userdata.tar"
        exit 1
    fi
}

# TODO Need to make sure to have /sbin on the PATH. Is there a better way?
# http://stackoverflow.com/questions/19983710/some-commands-not-wroking-on-remote-servers-through-ssh-shell
# https://github.com/LalatenduMohanty/centos-live-iso/issues/11
echo 'PATH=$PATH:/sbin' >> /home/docker/.bashrc

# If there is a partition with `boot2docker-data` as its label we are dealing with
# an already bootstrapped docker-machine. Just make sure to mount data partition and to unpack
# userdata.tar. Remember, /home/docker is not persistent
BOOT2DOCKER_DATA=`blkid -o device -l -t LABEL=$LABEL`
if [ -n "$BOOT2DOCKER_DATA" ]; then
    mount_partitions
    handle_user_data
    exit 0
fi

# Test for our magic string (it means that the disk was made by ./boot2docker init)
HEADER=`dd if=$UNPARTITIONED_HD bs=1 count=${#MAGIC} 2>/dev/null`
if [ "$HEADER" = "$MAGIC" ]; then
    # Read /userdata.tar with ssh keys and place it temporarily under /
    dd if=$UNPARTITIONED_HD of=/userdata.tar bs=1 count=4096 2>/dev/null

    prepare_partions
    mount_partitions
    handle_user_data
    exit 0
fi
